package com.pig4cloud.pigx.wxApi.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.security.annotation.Inner;


import com.pig4cloud.pigx.ruralLibrary.api.entity.terrainEntity;
import com.pig4cloud.pigx.ruralLibrary.api.feign.RemoteBookUserService;

import com.pig4cloud.pigx.wxApi.config.*;
import com.pig4cloud.pigx.wxApi.entity.*;
import com.pig4cloud.pigx.wxApi.service.UserInfoService;
import com.pig4cloud.pigx.wxApi.util.VerifyUtil;
import com.pig4cloud.pigx.wxApi.util.WxUntill;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Base64;
import java.util.Objects;

/**
 * 登录相关接口
 *
 * @author myg
 * @date 2023-07-19  16:06:24
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/user_login")
@Tag(description = "user_login", name = "登录相关接口")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class UserLoginController {
//    @Autowired
//	private AuthenticationManager authenticationManager;

	@Autowired
	private UserInfoService userInfoSerice;
	@Autowired
	private RedisTemplate redisTemplate;
	@Autowired
	private RemoteBookUserService remoteBookUserService;

	/**
	 * 获取手机号判断是否需要注册
	 *
	 * @return
	 */
	@Operation(summary = "获取手机号判断是否需要注册 true需要注册 false直接登录", description = "获取手机号判断是否需要注册 true需要注册 false直接登录")
	@PostMapping(value = "/isRegister")
	@Inner(false)
	public R isRegister(@RequestBody String code, HttpServletRequest request) throws IOException {
//		String phoneNum = WxUntill.getPhoneNum(code);
////		String phoneNum ="15617996096";
//		if (this.userInfoSerice.getUserByPhone(phoneNum) != null) {
//			UserInfo userByPhone = this.userInfoSerice.getUserByPhone(phoneNum);
////			JwtAuthenticatioToken token;
////			try {
//			//3.生成token信息
////				AuthenticationManager authenticationManager = this.authenticationManager;
////				token = SecurityUtils.login(request, userByPhone.getUserName(), userByPhone.getPassword(), this.authenticationManager);
//			//向redis里面存入数据，以用户号为主键
//			//向用户表里面存token数据
////				userByPhone.setPersonalWeb(token.getToken());
//			this.userInfoSerice.updateById(userByPhone);
//			return R.ok(Boolean.FALSE);
////			} catch (Exception e) {
////				return R.failed("您输入的账号或密码有误!");
////			}
//		} else {
//			return R.ok(Boolean.TRUE);
//		}
		String wxOpenid = WxUntill.getWxOpenid(code);
		LambdaQueryWrapper<SysUserInfo> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(SysUserInfo::getOpenId,wxOpenid);
		SysUserInfo one = userInfoSerice.getOne(wrapper);
		String phoneNum = WxUntill.getPhoneNum(code);
		if (one == null){
			return R.ok(phoneNum);
		}else {
			return R.ok();
		}

	}


	/**
	 * 注册接口
	 *
	 * @return
	 */
	@Operation(summary = "注册", description = "注册")
	@PostMapping(value = "/register")
	@Inner(false)
	public R register(@Valid @RequestBody RegisterBean registerBean, HttpServletRequest request) throws IOException {
		String code = registerBean.getCode();
		String mobile = registerBean.getMobile();
//		String username = registerBean.getMobile();
		//手机号注册 校验手机号是否被占用 校验验证码
		if (StringUtils.isNotEmpty(mobile)) {
			boolean isExsit = userInfoSerice.mobileExsit(mobile);
			if (isExsit) {
				return R.failed("该用户已存在");
			}
			String smsCode = (String) redisTemplate.opsForValue().get("sms-code-".concat(mobile));
			if (Objects.nonNull(smsCode)) {
				if (!Objects.equals(code, smsCode.toString())) {
					return R.failed("验证码错误");
				}
			} else {
				return R.failed("验证码错误");
			}
		}

		if (userInfoSerice.registerExt(registerBean)) {
//			JwtAuthenticatioToken token;
			//3.生成token信息
//			token = SecurityUtils.login(request, username, registerBean.getPassword(), authenticationManager);
			SysUserInfo userInfo = null;
			//2.校验用户是否存在
			if (StringUtils.isNotEmpty(mobile)) {
				userInfo = userInfoSerice.getUserByPhone(mobile);
			}
			//向用户表里面存token数据
//			UserInfo userByUserName = userInfoService.getUserByUserName(username);
//			userInfo.setPersonalWeb(token.getToken());
			String wxOpenid = WxUntill.getWxOpenid(code);
			userInfo.setOpenId(wxOpenid);
			userInfoSerice.updateById(userInfo);
			//4.组装响应数据

			UserLoginResp response = new UserLoginResp();
			response.setName(userInfo.getName());
			response.setNick(userInfo.getNick());
			response.setUserId(userInfo.getUserId().toString());
//			response.setToken(token.getToken());
			response.setCompanyName(userInfo.getCompanyName());
			response.setUserName(userInfo.getUserName());
			response.setEmail(userInfo.getEmail());
			response.setPhotoUrl(userInfo.getPhotoUrl());
			response.setCityName(userInfo.getCityName());
			response.setAreaName(userInfo.getAreaName());
			response.setStreetName(userInfo.getStreetName());
			response.setCommitteeName(userInfo.getCommitteeName());
			response.setOpenId(userInfo.getOpenId());
			response.setPhotoUrl("https://img1.baidu.com/it/u=1310564963,1641173348&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800");
			return R.ok(response);
		}
		return R.failed(Boolean.FALSE);
	}

	/**
	 * 登录接口
	 */
	@Operation(summary = "登陆", description = "登陆")
	@PostMapping(value = "/login")
	@Inner(false)
	public R login(@RequestBody LoginBean loginBean, HttpServletRequest request) throws IOException {
		String username = loginBean.getUsername();
		String password = loginBean.getPassword();
		//校验是否是邮箱或手机号
		boolean isPhone = VerifyUtil.isPhone(username);
		boolean isEmail = VerifyUtil.isEmail(username);
		SysUserInfo userInfo;
		String tip = "";
		//2.校验用户是否存在
		if (isPhone == true) {
			userInfo = userInfoSerice.getUserByPhone(username);
			tip = "此手机号未注册";
		} else if (isEmail == true) {
			userInfo = userInfoSerice.getUserByEmail(username);
		} else {
			return R.failed("用户不存在!");
			//log.info("---------------------------------------------------------");
			//return ApiResponseT.builder().success(true);
		}
		if (Objects.isNull(userInfo)) {
			return R.failed(tip);
		}
		if (userInfo.getStatus() != UserStatusEnum.ENABLE.getCode()) {
			return R.failed("当前用户为禁用状态,无法登录！");
		}
		//String enCodePassword=new MyPasswordEncoder().encode(password);
//		JwtAuthenticatioToken token;
//		try {
//			//3.生成token信息
////			token = SecurityUtils.login(request, username, password, authenticationManager);
//		} catch (Exception e) {
//			return R.failed("您输入的账号或密码有误!");
//		}
		//向redis里面存入数据，以用户号为主键
		//向用户表里面存token数据
//		userInfo.setPersonalWeb(token.getToken());
		userInfoSerice.updateById(userInfo);

		//4.组装响应数据
		UserLoginResp response = new UserLoginResp();
		response.setName(userInfo.getName());
		response.setNick(userInfo.getNick());
		response.setUserId(userInfo.getUserId().toString());
//		response.setToken(token.getToken());
		response.setOpenId(userInfo.getOpenId());
		response.setCompanyName(userInfo.getCompanyName());
		response.setUserName(userInfo.getUserName());
		response.setEmail(userInfo.getEmail());
		response.setPhotoUrl(userInfo.getPhotoUrl());
		response.setProvinceName("河南省");
		response.setCityName(userInfo.getCityName());
		response.setAreaName(userInfo.getAreaName());
		response.setCommitteeName(userInfo.getCommitteeName());
		response.setStreetName(userInfo.getStreetName());
		return R.ok(response);
	}


	/**
	 * 重新绑定位置
	 *
	 * @return
	 */
	@Operation(summary = "重新绑定位置", description = "重新绑定位置")
	@PostMapping(value = "/bindLocation")
	@Inner(false)
	public R bindLocation(@RequestParam(value = "code", required = true) String code, @RequestParam(value = "phone", required = true) String phone, HttpServletRequest request) throws IOException {
		boolean isExsit = userInfoSerice.mobileExsit(phone);
		if (!isExsit) {
			return R.failed("该用户不存在");
		}
		SysUserInfo userByPhone1 = userInfoSerice.getUserByPhone(phone);
		String decode = decode(code);
		terrainEntity summaryEntity = remoteBookUserService.getOne(decode.replace("\"", ""), SecurityConstants.FROM_IN);
		userByPhone1.setProvinceName("河南省");
		userByPhone1.setCityCode(summaryEntity.getCityCode() == null ? "" : summaryEntity.getCityCode());
		userByPhone1.setAreaCode(summaryEntity.getAreaCode() == null ? "" : summaryEntity.getAreaCode());
		userByPhone1.setCommitteeCode(summaryEntity.getCommitteeCode() == null ? "" : summaryEntity.getCommitteeCode());
		userByPhone1.setStreetCode(summaryEntity.getStreetCode() == null ? "" : summaryEntity.getStreetCode());
		userByPhone1.setCityName(summaryEntity.getCityName() == null ? "" : summaryEntity.getCityName());
		userByPhone1.setAreaName(summaryEntity.getAreaName() == null ? "" : summaryEntity.getAreaName());
		userByPhone1.setCommitteeName(summaryEntity.getCommitteeName() == null ? "" : summaryEntity.getCommitteeName());
		userByPhone1.setStreetName(summaryEntity.getStreetName() == null ? "" : summaryEntity.getStreetName());

		userInfoSerice.updateUserInfo(userByPhone1);
		return R.ok("重设位置成功");
	}

	/**
	 * 判断用户是否需要登录
	 *
	 * @return
	 */
	@Operation(summary = "判断用户是否需要登录", description = "判断用户是否需要登录")
	@PostMapping(value = "/isLogin")
	@Inner(false)
	public R isLogin(@RequestParam(value = "code", required = true) String code, HttpServletRequest request) throws IOException {
		String wxOpenid = WxUntill.getWxOpenid(code);
		LambdaQueryWrapper<SysUserInfo> eq = new LambdaQueryWrapper<SysUserInfo>().eq(SysUserInfo::getOpenId, wxOpenid);

		if(userInfoSerice.getOne(eq)==null)
		{
			return R.ok(Boolean.TRUE);
		}else{
			return R.ok(Boolean.FALSE);
		}
	}

	/**
	 * 解密
	 *
	 * @param encryptedText
	 * @return
	 */
	public String decode(String encryptedText) {
		String password = "0123456789ABCDEF0123456789ABCDEF"; // 解密密码
		try {
			// Base64 解码密文
			Security.addProvider(new BouncyCastleProvider());

			// Base64 解码密文
			byte[] decodedBytes = Base64.getDecoder().decode(encryptedText);

			// 创建 AES 密钥规范
			SecretKeySpec secretKey = new SecretKeySpec(password.getBytes(StandardCharsets.UTF_8), "AES");

			// 创建 AES 解密器，并设置 ECB 模式和 PKCS7 填充方式
			Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
			cipher.init(Cipher.DECRYPT_MODE, secretKey);

			// 解密
			byte[] decryptedBytes = cipher.doFinal(decodedBytes);
			String decryptedText = new String(decryptedBytes, StandardCharsets.UTF_8);

			return decryptedText;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Inner(value = false)
	@GetMapping("/getOne/{id}")
	public terrainEntity getOne(@PathVariable("id") String id) {
		return remoteBookUserService.getOne(id, SecurityConstants.FROM_IN);
	}
}
